home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / LoadSaveNoteVectors.c < prev    next >
Text File  |  1994-12-30  |  14KB  |  447 lines

  1. /* LoadSaveNoteVectors.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "LoadSaveNoteVectors.h"
  31. #include "Array.h"
  32. #include "FrameObject.h"
  33. #include "NoteObject.h"
  34. #include "Memory.h"
  35. #include "BufferedFileInput.h"
  36. #include "BufferedFileOutput.h"
  37.  
  38.  
  39. /* Note Vector Subblock Format: */
  40. /*   1-byte format version number */
  41. /*       should be 1 or 2 */
  42. /*   4-byte little endian number of frames in the vector */
  43. /*   * for each frame: */
  44. /*       4-byte little endian number of notes in the frame */
  45. /*       n-bytes of data for all of the notes (see note object format) */
  46. /*   4-byte little endian number of records in the tie matrix */
  47. /*   * for each tie matrix entry: */
  48. /*       4-byte little endian index of the source frame */
  49. /*       4-byte little endian index of the source note in the frame */
  50. /*       4-byte little endian index of the target frame */
  51. /*       4-byte little endian index of the target note in the frame */
  52.  
  53.  
  54. /* this reads in notes from the file and the tie matrix and builts a note */
  55. /* vector from the information. */
  56. FileLoadingErrors        ReadNoteVector(struct ArrayRec** FrameArrayOut,
  57.                                             struct BufferedInputRec* Input)
  58.     {
  59.         signed long                NumberOfFrames;
  60.         long                            FrameScan;
  61.         ArrayRec*                    FrameArray;
  62.         FileLoadingErrors    Error;
  63.         signed long                NumberOfTieRecords;
  64.         long                            TieScan;
  65.         unsigned char            UnsignedChar;
  66.         short                            FormatVersionNumber;
  67.  
  68.         CheckPtrExistence(Input);
  69.  
  70.         /*   1-byte format version number */
  71.         /*       should be 1 or 2 */
  72.         if (!ReadBufferedUnsignedChar(Input,&UnsignedChar))
  73.             {
  74.                 Error = eFileLoadDiskError;
  75.              FailurePointneg1:
  76.                 return Error;
  77.             }
  78.         if ((UnsignedChar != 1) && (UnsignedChar != 2))
  79.             {
  80.                 Error = eFileLoadBadFormat;
  81.              FailurePoint0:
  82.                 goto FailurePointneg1;
  83.             }
  84.         FormatVersionNumber = UnsignedChar;
  85.  
  86.         FrameArray = NewArray();
  87.         if (FrameArray == NIL)
  88.             {
  89.                 Error = eFileLoadOutOfMemory;
  90.              FailurePoint1:
  91.                 goto FailurePoint0;
  92.             }
  93.  
  94.         /*   4-byte little endian number of frames in the vector */
  95.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumberOfFrames))
  96.             {
  97.                 long                            FrameLimit;
  98.  
  99.                 Error = eFileLoadDiskError;
  100.              FailurePoint2:
  101.                 FrameLimit = ArrayGetLength(FrameArray);
  102.                 for (FrameScan = 0; FrameScan < FrameLimit; FrameScan += 1)
  103.                     {
  104.                         DisposeFrameAndContents((FrameObjectRec*)ArrayGetElement(
  105.                             FrameArray,FrameScan));
  106.                     }
  107.                 DisposeArray(FrameArray);
  108.                 goto FailurePoint1;
  109.             }
  110.         if (NumberOfFrames < 0)
  111.             {
  112.                 Error = eFileLoadBadFormat;
  113.              FailurePoint3:
  114.                 goto FailurePoint2;
  115.             }
  116.  
  117.         /*   * for each frame: */
  118.         /*       4-byte little endian number of notes in the frame */
  119.         /*       n-bytes of data for all of the notes */
  120.         for (FrameScan = 0; FrameScan < NumberOfFrames; FrameScan += 1)
  121.             {
  122.                 signed long                    NumberOfNotes;
  123.                 long                                NoteScan;
  124.                 FrameObjectRec*            FrameObject;
  125.  
  126.                 if (!ReadBufferedSignedLongLittleEndian(Input,&NumberOfNotes))
  127.                     {
  128.                         Error = eFileLoadDiskError;
  129.                      FailurePoint4:
  130.                         goto FailurePoint3;
  131.                     }
  132.  
  133.                 FrameObject = NewFrame();
  134.                 if (FrameObject == NIL)
  135.                     {
  136.                         Error = eFileLoadOutOfMemory;
  137.                      FailurePoint4a:
  138.                         goto FailurePoint4;
  139.                     }
  140.  
  141.                 for (NoteScan = 0; NoteScan < NumberOfNotes; NoteScan += 1)
  142.                     {
  143.                         NoteObjectRec*            Note;
  144.  
  145.                         Error = NoteObjectNewFromFile(&Note,Input,FormatVersionNumber);
  146.                         if (Error != eFileLoadNoError)
  147.                             {
  148.                              FailurePoint4b:
  149.                                 DisposeFrameAndContents(FrameObject);
  150.                                 goto FailurePoint4a;
  151.                             }
  152.  
  153.                         if (((NumNotesInFrame(FrameObject) > 1) && IsItACommand(Note))
  154.                             || IsThisACommandFrame(FrameObject))
  155.                             {
  156.                                 Error = eFileLoadBadFormat;
  157.                              FailurePoint4ba:
  158.                                 DisposeNote(Note);
  159.                                 goto FailurePoint4b;
  160.                             }
  161.  
  162.                         if (!AppendNoteToFrame(FrameObject,Note))
  163.                             {
  164.                                 Error = eFileLoadOutOfMemory;
  165.                              FailurePoint4bb:
  166.                                 goto FailurePoint4ba;
  167.                             }
  168.                     }
  169.  
  170.                 if (!ArrayAppendElement(FrameArray,FrameObject))
  171.                     {
  172.                         Error = eFileLoadOutOfMemory;
  173.                         goto FailurePoint4b;
  174.                     }
  175.             }
  176.  
  177.         /*   4-byte little endian number of records in the tie matrix */
  178.         if (!ReadBufferedSignedLongLittleEndian(Input,&NumberOfTieRecords))
  179.             {
  180.                 Error = eFileLoadDiskError;
  181.              FailurePoint5:
  182.                 goto FailurePoint4;
  183.             }
  184.         if (NumberOfTieRecords < 0)
  185.             {
  186.                 Error = eFileLoadBadFormat;
  187.              FailurePoint6:
  188.                 goto FailurePoint5;
  189.             }
  190.  
  191.         /*   * for each tie matrix entry: */
  192.         /*       4-byte little endian index of the source frame */
  193.         /*       4-byte little endian index of the source note in the frame */
  194.         /*       4-byte little endian index of the target frame */
  195.         /*       4-byte little endian index of the target note in the frame */
  196.         for (TieScan = 0; TieScan < NumberOfTieRecords; TieScan += 1)
  197.             {
  198.                 signed long                    SourceFrameIndex;
  199.                 signed long                    SourceNoteIndex;
  200.                 signed long                    TargetFrameIndex;
  201.                 signed long                    TargetNoteIndex;
  202.                 FrameObjectRec*            SourceFrame;
  203.                 FrameObjectRec*            TargetFrame;
  204.                 NoteObjectRec*            SourceNote;
  205.                 NoteObjectRec*            TargetNote;
  206.  
  207.                 if (!ReadBufferedSignedLongLittleEndian(Input,&SourceFrameIndex))
  208.                     {
  209.                         Error = eFileLoadDiskError;
  210.                      FailurePoint7:
  211.                         goto FailurePoint6;
  212.                     }
  213.                 if (SourceFrameIndex < 0)
  214.                     {
  215.                         Error = eFileLoadBadFormat;
  216.                      FailurePoint7a:
  217.                         goto FailurePoint7;
  218.                     }
  219.                 if (!ReadBufferedSignedLongLittleEndian(Input,&SourceNoteIndex))
  220.                     {
  221.                         Error = eFileLoadDiskError;
  222.                      FailurePoint7b:
  223.                         goto FailurePoint7a;
  224.                     }
  225.                 if (SourceNoteIndex < 0)
  226.                     {
  227.                         Error = eFileLoadBadFormat;
  228.                      FailurePoint7c:
  229.                         goto FailurePoint7b;
  230.                     }
  231.                 if (!ReadBufferedSignedLongLittleEndian(Input,&TargetFrameIndex))
  232.                     {
  233.                         Error = eFileLoadDiskError;
  234.                      FailurePoint7d:
  235.                         goto FailurePoint7c;
  236.                     }
  237.                 if (TargetFrameIndex < 0)
  238.                     {
  239.                         Error = eFileLoadBadFormat;
  240.                      FailurePoint7e:
  241.                         goto FailurePoint7d;
  242.                     }
  243.                 if (!ReadBufferedSignedLongLittleEndian(Input,&TargetNoteIndex))
  244.                     {
  245.                         Error = eFileLoadDiskError;
  246.                      FailurePoint7f:
  247.                         goto FailurePoint7e;
  248.                     }
  249.                 if (TargetNoteIndex < 0)
  250.                     {
  251.                         Error = eFileLoadBadFormat;
  252.                      FailurePoint7g:
  253.                         goto FailurePoint7f;
  254.                     }
  255.                 if ((TargetFrameIndex <= SourceFrameIndex)
  256.                     || (TargetFrameIndex >= ArrayGetLength(FrameArray))
  257.                     || (SourceFrameIndex >= ArrayGetLength(FrameArray)))
  258.                     {
  259.                         Error = eFileLoadBadFormat;
  260.                      FailurePoint7h:
  261.                         goto FailurePoint7g;
  262.                     }
  263.                 SourceFrame = (FrameObjectRec*)ArrayGetElement(FrameArray,SourceFrameIndex);
  264.                 CheckPtrExistence(SourceFrame);
  265.                 TargetFrame = (FrameObjectRec*)ArrayGetElement(FrameArray,TargetFrameIndex);
  266.                 CheckPtrExistence(TargetFrame);
  267.                 if ((SourceNoteIndex >= NumNotesInFrame(SourceFrame))
  268.                     || (TargetNoteIndex >= NumNotesInFrame(TargetFrame)))
  269.                     {
  270.                         Error = eFileLoadBadFormat;
  271.                      FailurePoint7i:
  272.                         goto FailurePoint7h;
  273.                     }
  274.                 SourceNote = GetNoteFromFrame(SourceFrame,SourceNoteIndex);
  275.                 CheckPtrExistence(SourceNote);
  276.                 TargetNote = GetNoteFromFrame(TargetFrame,TargetNoteIndex);
  277.                 CheckPtrExistence(TargetNote);
  278.                 if (IsItACommand(SourceNote) || IsItACommand(TargetNote))
  279.                     {
  280.                         Error = eFileLoadBadFormat;
  281.                      FailurePoint7j:
  282.                         goto FailurePoint7i;
  283.                     }
  284.                 PutNoteTieTarget(SourceNote,TargetNote);
  285.             }
  286.  
  287.         *FrameArrayOut = FrameArray;
  288.         return eFileLoadNoError;
  289.     }
  290.  
  291.  
  292. /* this writes out the information for each note and then writes the tie matrix */
  293. /* to the file. */
  294. FileLoadingErrors        WriteNoteVector(struct ArrayRec* ArrayOfFrames,
  295.                                             struct BufferedOutputRec* Output)
  296.     {
  297.         long                            NumberOfFrames;
  298.         long                            FrameScan;
  299.         long                            NumberOfTieRecords;
  300.  
  301.         CheckPtrExistence(ArrayOfFrames);
  302.         CheckPtrExistence(Output);
  303.  
  304.         /*   1-byte format version number */
  305.         /*       should be 1 or 2 */
  306.         if (!WriteBufferedUnsignedChar(Output,2))
  307.             {
  308.                 return eFileLoadDiskError;
  309.             }
  310.  
  311.         /*   4-byte little endian number of frames in the vector */
  312.         NumberOfFrames = ArrayGetLength(ArrayOfFrames);
  313.         if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfFrames))
  314.             {
  315.                 return eFileLoadDiskError;
  316.             }
  317.  
  318.         /*   * for each frame: */
  319.         /*       4-byte little endian number of notes in the frame */
  320.         /*       n-bytes of data for all of the notes */
  321.         NumberOfTieRecords = 0;
  322.         for (FrameScan = 0; FrameScan < NumberOfFrames; FrameScan += 1)
  323.             {
  324.                 FrameObjectRec*        Frame;
  325.                 long                            NumberOfNotes;
  326.                 long                            NoteScan;
  327.                 FileLoadingErrors    Error;
  328.  
  329.                 Frame = (FrameObjectRec*)ArrayGetElement(ArrayOfFrames,FrameScan);
  330.                 CheckPtrExistence(Frame);
  331.                 NumberOfNotes = NumNotesInFrame(Frame);
  332.                 if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfNotes))
  333.                     {
  334.                         return eFileLoadDiskError;
  335.                     }
  336.                 for (NoteScan = 0; NoteScan < NumberOfNotes; NoteScan += 1)
  337.                     {
  338.                         NoteObjectRec*        Note;
  339.  
  340.                         Note = GetNoteFromFrame(Frame,NoteScan);
  341.                         if (!IsItACommand(Note) && (GetNoteTieTarget(Note) != NIL))
  342.                             {
  343.                                 NumberOfTieRecords += 1;
  344.                             }
  345.                         Error = NoteObjectWriteDataOut(Note,Output);
  346.                         if (Error != eFileLoadNoError)
  347.                             {
  348.                                 return Error;
  349.                             }
  350.                     }
  351.             }
  352.  
  353.         /*   4-byte little endian number of records in the tie matrix */
  354.         if (!WriteBufferedSignedLongLittleEndian(Output,NumberOfTieRecords))
  355.             {
  356.                 return eFileLoadDiskError;
  357.             }
  358.  
  359.         /*   * for each tie matrix entry: */
  360.         /*       4-byte little endian index of the source frame */
  361.         /*       4-byte little endian index of the source note in the frame */
  362.         /*       4-byte little endian index of the target frame */
  363.         /*       4-byte little endian index of the target note in the frame */
  364.         for (FrameScan = 0; FrameScan < NumberOfFrames; FrameScan += 1)
  365.             {
  366.                 FrameObjectRec*        Frame;
  367.                 long                            NumberOfNotes;
  368.                 long                            NoteScan;
  369.  
  370.                 Frame = (FrameObjectRec*)ArrayGetElement(ArrayOfFrames,FrameScan);
  371.                 CheckPtrExistence(Frame);
  372.                 NumberOfNotes = NumNotesInFrame(Frame);
  373.                 for (NoteScan = 0; NoteScan < NumberOfNotes; NoteScan += 1)
  374.                     {
  375.                         NoteObjectRec*        Note;
  376.  
  377.                         Note = GetNoteFromFrame(Frame,NoteScan);
  378.                         if (!IsItACommand(Note))
  379.                             {
  380.                                 NoteObjectRec*        TieTarget;
  381.  
  382.                                 TieTarget = GetNoteTieTarget(Note);
  383.                                 if (TieTarget != NIL)
  384.                                     {
  385.                                         long                            SubFrameScan;
  386.  
  387.                                         NumberOfTieRecords -= 1;
  388.                                         for (SubFrameScan = FrameScan + 1; SubFrameScan < NumberOfFrames;
  389.                                             SubFrameScan += 1)
  390.                                             {
  391.                                                 FrameObjectRec*        SearchFrame;
  392.                                                 long                            SubNumNotes;
  393.                                                 long                            SubNoteScan;
  394.  
  395.                                                 SearchFrame = (FrameObjectRec*)ArrayGetElement(ArrayOfFrames,
  396.                                                     SubFrameScan);
  397.                                                 CheckPtrExistence(SearchFrame);
  398.                                                 SubNumNotes = NumNotesInFrame(SearchFrame);
  399.                                                 for (SubNoteScan = 0; SubNoteScan < SubNumNotes; SubNoteScan += 1)
  400.                                                     {
  401.                                                         NoteObjectRec*        SearchNote;
  402.  
  403.                                                         SearchNote = GetNoteFromFrame(SearchFrame,SubNoteScan);
  404.                                                         if (!IsItACommand(SearchNote))
  405.                                                             {
  406.                                                                 if (SearchNote == TieTarget)
  407.                                                                     {
  408.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  409.                                                                             Output,FrameScan))
  410.                                                                             {
  411.                                                                                 return eFileLoadDiskError;
  412.                                                                             }
  413.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  414.                                                                             Output,NoteScan))
  415.                                                                             {
  416.                                                                                 return eFileLoadDiskError;
  417.                                                                             }
  418.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  419.                                                                             Output,SubFrameScan))
  420.                                                                             {
  421.                                                                                 return eFileLoadDiskError;
  422.                                                                             }
  423.                                                                         if (!WriteBufferedSignedLongLittleEndian(
  424.                                                                             Output,SubNoteScan))
  425.                                                                             {
  426.                                                                                 return eFileLoadDiskError;
  427.                                                                             }
  428.                                                                         goto DoneSearchingForTieTargetPoint;
  429.                                                                     }
  430.                                                             }
  431.                                                     }
  432.                                             }
  433.                                         EXECUTE(PRERR(ForceAbort,
  434.                                             "WriteNoteVector:  tie target couldn't be found"));
  435.                                         /* jump out here when tie target has been found */
  436.                                      DoneSearchingForTieTargetPoint:
  437.                                         ;
  438.                                     }
  439.                             }
  440.                     }
  441.             }
  442.         ERROR(NumberOfTieRecords != 0,PRERR(ForceAbort,
  443.             "WriteNoteVector:  tie record count inconsistency"));
  444.  
  445.         return eFileLoadNoError;
  446.     }
  447.